package com.fowo.api.syncAmazon.monitor;

import com.fowo.api.syncAmazon.mapper.ApiRequestLogMapper;
import com.fowo.api.syncAmazon.model.ApiMonitoringInfo;
import com.fowo.api.sys.service.impl.SysMailServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @description: 拉取数据的API监控
 * @author: xqw
 * @time: 2024/4/25 17:12
 */
@Slf4j
@Component
public class SyncDataMonitor {
    @Autowired
    protected ApiRequestLogMapper apiRequestLogMapper;

    @Autowired
    protected SysMailServiceImpl sysMailService;

    @Value("${spring.mail.addressee}")
    private String addressee;

    private static String EMAIL_SUBJECT_PREFIX = "'亚马逊数据拉取任务监控报警--";

    /**
     * 监控任务入口
     */
    public void entrance(Boolean isSummary) {
        // 未传参数，默认为 false :监控告警任务
        if (isSummary == null || !isSummary) {
            isSummary = false;
        } else {
            EMAIL_SUBJECT_PREFIX = "'亚马逊数据拉取任务汇总--";
        }

        // 获取 拉取数据的API 数据
        Map<String, Object> result = prepare();

        // 验证是否触发告警邮件
        boolean isWarn = verify(result);

        // 触发告警，汇总任务必须要发邮件
        if (isWarn || isSummary) {
            // 构造监控告警模板数据
            Map<String, Object> variables = createTemplateData(result);

            // 发送邮件
            try {
                sysMailService.send(addressee, EMAIL_SUBJECT_PREFIX + LocalDate.now() + "'", "request-api-alarm.html", variables);
            } catch (MessagingException e) {
                log.error("数据拉取API报警邮件发送失败", e);
                throw new RuntimeException(e);
            }
        }
    }

    public Map<String, Object> createTemplateData(Map<String, Object> result) {
        Map<String, Object> variables = new HashMap<>();

        List<ApiMonitoringInfo> info = (List<ApiMonitoringInfo>) result.get("info");
        List<String> noRequestApi = (List<String>) result.get("noRequestApi");


        //  成功次数、数据量、耗时、最新的拉取时间段
        List<Map<String, Object>> successList = new ArrayList<>();
        for (ApiMonitoringInfo apiMonitoringInfo : info) {
            Map<String, Object> map = new HashMap<>();
            map.put("apiCode", apiMonitoringInfo.getApiCode());
            map.put("requestSuccessCount", apiMonitoringInfo.getRequestSuccessCount());
            map.put("dataVolume", apiMonitoringInfo.getDataVolume());
            // 耗时转换为秒单位
            map.put("consumeTime", apiMonitoringInfo.getConsumeTime() / 1000);
            map.put("lastStartTime", apiMonitoringInfo.getLastStartTime());
            map.put("lastEndTime", apiMonitoringInfo.getLastEndTime());
            map.put("requestFailCount", apiMonitoringInfo.getRequestFailCount());
            successList.add(map);
        }
        variables.put("successList", successList);

        // 24小时内无数据拉取的api
        List<Map<String, Object>> noRequestList = new ArrayList<>();
        for (String s : noRequestApi) {
            Map<String, Object> map = new HashMap<>();
            map.put("apiCode", s);
            noRequestList.add(map);
        }
        variables.put("noRequestList", noRequestList);
        return variables;
    }

    /**
     * 验证查询结果是否需要触发告警邮件, 成功的数量为0，发出邮件警报
     *
     * @param result 查询的结果集
     * @return 是否触发告警邮件
     */
    public boolean verify(Map<String, Object> result) {
        if (result == null) {
            return false;
        }

        List<ApiMonitoringInfo> info = (List<ApiMonitoringInfo>) result.get("info");
        if (info != null && info.size() > 0) {
            for (ApiMonitoringInfo apiMonitoringInfo : info) {
                if (apiMonitoringInfo.getRequestSuccessCount() <= 0) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取结果集
     *
     * @return 查询结果
     */
    public Map<String, Object> prepare() {
        Map<String, Object> result = new HashMap<>();

        // 24小时内数据拉取的统计数据， 成功次数、数据量、耗时、最新的拉取时间段 ，失败次数
        List<ApiMonitoringInfo> info = apiRequestLogMapper.getApiMonitoringInfo();
        result.put("info", info);

        // 24小时内无数据拉取的api
        List<String> noRequestApi = apiRequestLogMapper.getApiCodeOfNotRun();
        result.put("noRequestApi", noRequestApi);
        return result;
    }

}
